#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QString"
#include "QDir"
#include "QFileDialog"
#include "QDateTime"
#include "QPixmap"
#include "QImage"
#include "opencv2/opencv.hpp"
#include "QDebug"
#include "QErrorMessage"
using namespace  cv;
using namespace  std;

cv::Mat qim2mat(const QImage& image)
{
    qDebug()<< "format:"<<image.format();
    switch(image.format())
    {
        // 8-bit, 4 channel
        case QImage::Format_ARGB32:
            {//!!!
                cv::Mat mat(image.height(),image.width(),
                            CV_8UC4,
                            (void*)image.constBits(),
                            image.bytesPerLine());

                 // drop the all-white alpha channel
                cv::cvtColor(mat, mat, cv::COLOR_BGRA2BGR);
//                    imshow("cvmat",mat);
//                    waitKey(0);
                return mat.clone();
            }
        case QImage::Format_ARGB32_Premultiplied:
            {
                cv::Mat mat(image.height(), image.width(),
                            CV_8UC4,
                            (void*)image.constBits(),
                            image.bytesPerLine());
                return mat.clone();
            }

        // 8-bit, 3 channel
        case QImage::Format_RGB32:
            {
        //!!
                cv::Mat mat(image.height(),image.width(),
                            CV_8UC4,
                            (void*)image.constBits(),
                            image.bytesPerLine());

                 // drop the all-white alpha channel
                cv::cvtColor(mat, mat, cv::COLOR_BGRA2BGR);
                return mat.clone();
            }
        case QImage::Format_RGB888:
            {
                QImage swapped = image.rgbSwapped();
                cv::Mat mat(swapped.height(), swapped.width(),
                            CV_8UC3,
                            (void*)image.constBits(),
                            image.bytesPerLine());
                return mat.clone();
            }

        // 8-bit, 1 channel
        case QImage::Format_Indexed8:
            {
                cv::Mat mat(image.height(),image.width(),
                            CV_8UC1,
                            (void*)image.constBits(),
                            image.bytesPerLine());
                return mat.clone();
            }
        case QImage::Format_Grayscale8:
            {
        //!!
                cv::Mat mat(image.height(),image.width(),
                            CV_8UC1,
                            (void*)image.constBits(),
                            image.bytesPerLine());
                return mat.clone();
            }
        // wrong
        default:
            qDebug() << "ERROR: QImage could not be converted to Mat.";
            {
                QErrorMessage errorMessage;
                errorMessage.showMessage(
                    ("images not supported , </ br> type:"+std::to_string(image.format())).c_str());
                errorMessage.exec();
            }
            break;
    }

    return cv::Mat();
}
QImage mat2qim(Mat & mat)
{
    if(mat.channels() == 1){
        cvtColor(mat, mat, COLOR_GRAY2RGB);

    }else{
        cvtColor(mat, mat, COLOR_BGR2RGB);
    }
    QImage qim((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step,
        QImage::Format_RGB888);
    return qim;
}
//Mat qim2mat(QImage & qim)
//{
//    Mat mat = Mat(qim.height(), qim.width(),
//        CV_8UC3,(void*)qim.constBits());//,qim.bytesPerLine()
//    imshow("cvmat",mat);
//    waitKey(0);
//    return mat;
//}
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}
QString PathNameOrg,PathNameMask,current_File;
QDateTime current_File_time;
QImage imageOrg,imageMask, imageMerge;
bool isOrgLoaded = false;
//void MainWindow::resizeEvent(QResizeEvent *event){
//    qDebug()<<"resize event";
//};
void MainWindow::on_pushButton_clicked()
{
    QDir dir;
  PathNameOrg = QFileDialog::getOpenFileName(this, tr("Open file"),"/home/",
                                               "Image Files(*.jpg *.jpeg *.png *.bmp)");
  ui->PathShow->setText(PathNameOrg);    //文件名称显示
  imageOrg= QImage(PathNameOrg);
  //suoxiao
  Mat tmp = qim2mat(imageOrg);
  cv::Mat tmpsmall;
  //cv::Size(tmp.cols/4,tmp.rows/4)
  cv::resize(tmp,tmpsmall,cv::Size(480,640));
  qDebug()<< "org size:"<<tmpsmall.cols << ","<<tmpsmall.rows<<endl;
  imageOrg = mat2qim(tmpsmall);

  imageOrg.scaled(ui->labelimg->size(), Qt::KeepAspectRatio);
  ui->labelimg->setScaledContents(true);
  ui->labelimg->setPixmap(QPixmap::fromImage(imageOrg));
  isOrgLoaded = true;
}

void MainWindow::on_pushButton_2_clicked()
{
    QDir dir;
  PathNameMask = QFileDialog::getOpenFileName(this, tr("Open file"),"/home/",
                                               "Image Files(*.jpg *.jpeg *.png *.bmp)");
  ui->PathShow->setText(PathNameMask);    //文件名称显示
  imageMask= QImage(PathNameMask);
  Mat tmp = qim2mat(imageMask);
  cv::Mat tmpsmall;
  //cv::Size(tmp.cols/4,tmp.rows/4)
  cv::resize(tmp,tmpsmall,cv::Size(480,640));
  qDebug()<< "mask size:"<<tmpsmall.cols << ","<<tmpsmall.rows<<endl;
  imageMask = mat2qim(tmpsmall);
//  imageMask.scaled(ui->labelimg->size(), Qt::KeepAspectRatio);
//  ui->labelimg->setScaledContents(true);
//  ui->labelimg->setPixmap(QPixmap::fromImage(imageMask));
}
Mat calcuResult(Mat& matorg, Mat& matmask){
    Mat result;
//    imshow("org",matorg);
//    imshow("mask",matmask);
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));
//    dilate(matmask,matmask,element);

    vector<Mat>  channels;
    split(matmask, channels);
    cv::split(matmask, channels);
    for (int iColor = 0;iColor < 2;iColor ++)
    {
        channels[iColor] = Mat(channels[iColor].rows,channels[iColor].cols,
                               CV_8UC1);
        memset(channels[iColor].data,0,channels[iColor].rows*channels[iColor].cols);
    }
    cv::merge(channels,matmask);
    if(matorg.cols != matmask.cols || matmask.rows!= matorg.rows){
        QErrorMessage errorMessage;
        errorMessage.showMessage(
            "image size not equal!");
        errorMessage.exec();
        return Mat ();
    }
    addWeighted(matorg,1.0,matmask,1.0,0,result);     //图像叠加
//    imshow("dst",result);
//    waitKey(0);
    return result;
}
void MainWindow::on_pushButton_merge_clicked()
{
    if(!isOrgLoaded)
    {
        QErrorMessage errorMessage;
        errorMessage.showMessage(
            "No images loaded, </ br> please load an images before add mask!");
        errorMessage.exec();
        return;
    }
    on_pushButton_2_clicked();
//    imageMerge = imageOrg*imageMask;
    auto matorg = qim2mat(imageOrg);
    auto matmask = qim2mat(imageMask);
    cv::imshow("org.jpg",matorg);
    cv::imshow("mask.jpg",matmask);
    if (matmask.channels() ==1)
    {
        matmask = qim2mat(mat2qim(matmask));
    };
    if (matorg.channels() == 1)
    {
        matorg = qim2mat(mat2qim(matorg));
    };

    Mat dst=calcuResult(matorg,matmask);
    cv::imshow("dst.jpg",dst);
    auto dstimage = mat2qim(dst);
    dstimage.scaled(ui->labelimg->size(), Qt::KeepAspectRatio);
    ui->labelimg->setScaledContents(true);
    ui->labelimg->setPixmap(QPixmap::fromImage(dstimage));

}
